/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package recognizer;

/**
 * CS354 P1
 * @author Sam Jenkins
 */
public class Recognizer {

    private char LEFT_PARENTHESIS = 40;
    private char RIGHT_PARENTHESSIS = 41;
    private char COMMA = 44;
    private char LEFT_BRACKET = 91;
    private char RIGHT_BRACKET = 93;
    private char x = 120;
    private char y = 121;
    private char z = 122;
    private int syntaxLength = 0;
    private String syntax = null;
    private char lookAhead;
    private int i = 0;

    public Recognizer() {
    }

    public boolean isSyntaxValid(String syntax) {
        syntax = syntax.replace(" ", "");
        syntaxLength = syntax.length();
        if (syntaxLength >= 1) {
            this.syntax = syntax;
            this.next();
            boolean isSyntaxValid = pop();
            if (syntaxLength >= i+2) {
                return false;
            } else {
                return isSyntaxValid;
            }
        }
        return false;
    }

    protected void next() {
        if (i < syntaxLength) {
            lookAhead = syntax.charAt(i);
            i++;
        } else {
            lookAhead = 0;
        }
    }

    protected boolean checkFor(char ch) {
        if (lookAhead == ch) {
            if (i <= syntaxLength) {
                this.next();
            }
            return true;
        }
        return false;
    }

    /**
     * Method pop
     * Parses string in the language generated by the rule:
     * <pop> -> [<bop>,<pop>]|<bop>
     * @return
     */
    protected boolean pop() {
        if (this.checkFor(LEFT_BRACKET)) {
            if (this.bop() && this.checkFor(COMMA) && this.pop() && this.checkFor(RIGHT_BRACKET)) {
                return true;
            } else {
                return false;
            }
        }
        if (this.bop()) {
            return true;
        }
        return false;
    }

    /**
     * Method bop
     * Parses string in the language generated by the rule:
     * <bop> -> <boop>|(<pop>)
     * @return
     */
    protected boolean bop() {
        if (this.boop()) {
            return true;
        } else if (this.checkFor(LEFT_PARENTHESIS) && this.pop() && this.checkFor(RIGHT_PARENTHESSIS)) {
            return true;
        }
        return false;
    }

    /**
     * Method boop
     * Parses string in the language generated by the rule:
     * <boop> -> x|y|z
     * @return
     */
    protected boolean boop() {
        if (lookAhead == x || lookAhead == y || lookAhead == z) {
            this.next();
            return true;
        }
        return false;
    }
}
